//
//  VVOrmConfig.h
//  VVSequelize
//
//  Created by Valo on 2018/9/10.
//

#import <Foundation/Foundation.h>
/// record create time
FOUNDATION_EXPORT NSString *const kVVCreateAt;
/// record update time
FOUNDATION_EXPORT NSString *const kVVUpdateAt;

@class VVDatabase,VVForeignKey;
/// ORM configuration
@interface VVOrmConfig : NSObject
/// corresponding model, objective-c class
@property (nonatomic, strong) Class cls;
/// record time or not, default is NO
@property (nonatomic, assign) BOOL logAt;

//MARK: fts table configuration
/// fts table or not, default is NO
@property (nonatomic, assign) BOOL fts;
/// fts tokenize module, fts3,fts4,fts5; default is fts5
@property (nonatomic, copy) NSString *ftsModule;
/// fts tokenizer, such as: porter, unicode61, icu,...
@property (nonatomic, copy) NSString *ftsTokenizer;

//MARK: table parameters
/// self-increasing primary key or not
@property (nonatomic, assign) BOOL pkAutoInc;
/// all field names
@property (nonatomic, strong) NSArray<NSString *> *columns;
/// fields of primary keys
@property (nonatomic, strong) NSArray<NSString *> *primaries;
/// white list
@property (nonatomic, strong) NSArray<NSString *> *whiteList;
/// black list, if white list exists, use white list
@property (nonatomic, strong) NSArray<NSString *> *blackList;
/// non null constraints
@property (nonatomic, strong) NSArray<NSString *> *notnulls;
/// unique constraints
@property (nonatomic, strong) NSArray<NSString *> *uniques;
/// index fields
@property (nonatomic, strong) NSArray<NSString *> *indexes;
/// field type mapping,{field:type}
@property (nonatomic, strong) NSDictionary<NSString *, NSString *> *types;
/// field default values; {field: value}: value can be NSString,NSNumber,NSData
@property (nonatomic, strong) NSDictionary<NSString *, id> *defaultValues;

#ifdef VVSEQUELIZE_CONSTRAINTS
/// foreign keys
@property (nonatomic, strong) NSArray<VVForeignKey *> *foreignKeys;
/// check constraint; [expression]: expression is similar to `field > 0`
@property (nonatomic, strong) NSArray<NSString *> *checks;
#endif

//MARK: read-only properties
/// fts version
@property (nonatomic, assign, readonly) NSUInteger ftsVersion;
/// generated by table or not
@property (nonatomic, assign, readonly) BOOL fromTable;

//MARK: - Public
/// create configuration from an existing table
+ (instancetype)configFromTable:(NSString *)tableName
                       database:(VVDatabase *)vvdb;

/// create configuration from a objective-c class
+ (instancetype)configWithClass:(Class)cls;

/// create fts configuration from a objective-c class
/// @param cls objective-c class
/// @param indexes fields requiring full-text indexing, valid only in versions above fts4
+ (instancetype)ftsConfigWithClass:(Class)cls
                            module:(NSString *)module
                         tokenizer:(NSString *)tokenizer
                           indexes:(NSArray<NSString *> *)indexes;

/// duplication, deal with black and white list, etc.
- (void)treate;

/// compare with an other configuratioin
- (BOOL)isEqualToConfig:(VVOrmConfig *)config;

/// compare indexes with an other configuration
- (BOOL)isInedexesEqual:(VVOrmConfig *)config;

/// alert new column
- (NSString *)alertSQLOfColumn:(NSString *)column table:(NSString *)tableName;

/// generate common table SQL statement
- (NSString *)createSQLWith:(NSString *)tableName;

/// generate fts table SQL statement
- (NSString *)createFtsSQLWith:(NSString *)tableName
                 content_table:(NSString *)content_table
                 content_rowid:(NSString *)content_rowid;

@end
